﻿using GameTools.Data.ConfigData;
using GameTools.Data.DataType;
using GameTools.Service.ConfigServer;
using GameTools.Service.Nlog;
using GameTools.Services.ScriptExecutionService;
using GameTools.Utils;
using Newtonsoft.Json.Linq;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace GameTools.ViewModels
{
	public class XiYouPageViewModel : BindableBase
	{
        #region 数据
        private ObservableCollection<LogItem> _logItems;
        public ObservableCollection<LogItem> LogItems
        {
            get => _logItems;
            set => SetProperty(ref _logItems, value); // 使用 Prism 的 SetProperty 触发通知
        }

        private string _inputKey;
        public string InputKey
        {
            get => _inputKey;
            set => SetProperty(ref _inputKey, value);
        }

        public ObservableCollection<JsonNode> RootItems { get; set; } = new();

        private JObject _jsonRoot;

        private JObject _sheetJson;

        private ObservableCollection<JsonListItem> _flatItems = new();
        public ObservableCollection<JsonListItem> FlatItems
        {
            get => _flatItems;
            set => SetProperty(ref _flatItems, value);
        }

        private JsonListItem _selectedItem;
        public JsonListItem SelectedItem
        {
            get => _selectedItem;
            set
            {
                SetProperty(ref _selectedItem, value);
                //SelectedItemChangedCommand.Execute();
            }
        }

        #endregion

        #region 命令
        public DelegateCommand OneKeyExporConfigCommand {  get; set; }

        public DelegateCommand OneKeyCreateSheetJsonCommand {  get; set; }

        public DelegateCommand QueryCommand { get; set; }

        public DelegateCommand SelectedItemChangedCommand { get; set; }

        #endregion

        #region 服务
        private readonly ILogService _logService;
        private readonly IConfigService _configService;
        #endregion

        #region 配置
        private XiYouConfig _xiYouConfig;
        #endregion

        private readonly ScriptExecutionService _scriptService = new ScriptExecutionService();

        public XiYouPageViewModel(ILogService logService, IConfigService configService)
        {
            _logService = logService;
            _configService = configService;
            InitCommand();
            InitData();
            InitConfigAsync();
        }

        private void InitData()
        {
            _logItems = _logService.LogItems;
        }

        private async Task InitConfigAsync()
        {
            _logService.LogInfo("======开始检查配置文件======");
           _xiYouConfig = await _configService.LoadConfigAsync<XiYouConfig>("XiYouConfig.json");
            _logService.LogInfo("XiYouConfig加载完毕...");
            _jsonRoot = await _configService.ImportAndLoadConfigAsync(
                _xiYouConfig.Path.ExcelToLuaJsonPath,
                "config.json"
            );
            _logService.LogInfo("配置config导入并加载完成");
            try
            {
                _sheetJson = _configService.LoadConfig<JObject>("sheet_data.json");
                _logService.LogInfo("配置sheet_data导入并加载完成");
            }
            catch (Exception ex)
            {
                _logService.LogError($"加载 sheet_data.json 失败：{ex.Message}");
            }

        }

        private void InitCommand()
        {
            OneKeyExporConfigCommand = new DelegateCommand(OneKeyExporConfig);
            OneKeyCreateSheetJsonCommand = new DelegateCommand(OneKeyCreateSheetJsonHandle);
            QueryCommand = new DelegateCommand(OnQueryListView);
            SelectedItemChangedCommand = new DelegateCommand(OnSelectedItemChanged);
        }

        private async void OneKeyExporConfig()
        {
            var path = _xiYouConfig.Path.OneKeyExportBatPath;
            _logService.LogInfo("开始执行: " + path);

            var (success, output) = await _scriptService.ExecuteScriptAsync(
                path,
                "",
                ScriptMode.Observe,
                logCallback: (log) => _logService.LogInfo(log));

            _logService.LogInfo("执行完成");
            if (success)
                MessageBox.Show($"执行成功:\n{output}", "结果", MessageBoxButton.OK, MessageBoxImage.Information);
            else
                MessageBox.Show($"执行失败:\n{output}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }

        public async void OneKeyCreateSheetJsonHandle()
        {
            var excelPath = _xiYouConfig.Path.ExcelPath;
            // 获取脚本路径
            string scriptPath = PathHelper.GetPythonScriptPath("init_excel_sheet.py", "GameXiYou");
            // 获取目标目录（作为参数传入）
            string arguments = PathHelper.WrapArg(excelPath);
            // 执行
            _logService.LogInfo("开始执行: "+ scriptPath);
            var result = await _scriptService.ExecuteScriptAsync(scriptPath, arguments,
                ScriptMode.Observe,
                logCallback: (log) => _logService.LogInfo(log));
            _logService.LogInfo("执行: " + scriptPath + "完成");
        }


        private void OnQueryListView()
        {
            FlatItems.Clear();

            if (_jsonRoot.TryGetValue(InputKey, out var token))
            {
                List<JsonListItem> tempList = new();

                if (token is JObject obj)
                {
                    foreach (var prop in obj.Properties())
                    {
                        tempList.Add(new JsonListItem
                        {
                            Key = prop.Name,
                            Value = prop.Value.ToString()
                        });
                    }

                    // 按 Key 忽略大小写排序
                    var sorted = tempList.OrderBy(item => item.Key, StringComparer.OrdinalIgnoreCase);

                    foreach (var item in sorted)
                    {
                        FlatItems.Add(item);
                    }
                }
                else
                {
                    FlatItems.Add(new JsonListItem
                    {
                        Key = InputKey,
                        Value = token.ToString()
                    });
                }
            }
        }



        private void OnSelectedItemChanged()
        {
            if (SelectedItem == null || string.IsNullOrWhiteSpace(SelectedItem.Value))
                return;

            try
            {
                var parts = SelectedItem.Value.Split('.');
                var key = parts.Last();

                if (!_sheetJson.TryGetValue(key, out var token) || token.Type != JTokenType.Array)
                {
                    MessageBox.Show($"未找到键：{key}", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                var candidatePaths = token.Select(t => t.ToString()).ToList();

                if (candidatePaths.Count == 1)
                {
                    OpenExcelFile(candidatePaths[0]);
                    return;
                }

                // 多项时使用路径前缀进一步匹配
                var folderPrefix = string.Join("\\", parts.Take(parts.Length - 1)); // 转换为路径格式

                var matchedPath = candidatePaths
                    .FirstOrDefault(p => p.Replace("/", "\\").ToLower().Contains(folderPrefix.ToLower()));

                if (!string.IsNullOrEmpty(matchedPath))
                {
                    OpenExcelFile(matchedPath);
                }
                else
                {
                    MessageBox.Show($"未能根据路径前缀 '{folderPrefix}' 匹配到唯一文件。\n候选数：{candidatePaths.Count}",
                        "未匹配", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"处理错误：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private string? TryRecursivePathMatch(string[] parts, List<string> paths, int index)
        {
            if (index < 0)
                return null;

            // 组合后缀路径，例如：superrebate\\text、huodong\\superrebate\\text
            var subPathParts = parts.Skip(index).ToArray(); // 从 index 开始到末尾
            var searchPath = string.Join("\\", subPathParts); // 组合为 huodong\superrebate\text

            var matched = paths
                .Where(p => p.Replace("/", "\\").Contains(searchPath, StringComparison.OrdinalIgnoreCase))
                .ToList();

            if (matched.Count == 1)
            {
                return matched[0];
            }
            else if (matched.Count > 1)
            {
                // 多个匹配，继续往前缩小范围
                return TryRecursivePathMatch(parts, matched, index - 1);
            }

            // 当前未匹配，尝试更短前缀
            return TryRecursivePathMatch(parts, paths, index - 1);
        }

        private void OpenExcelFile(string path)
        {
            try
            {
                if (!File.Exists(path))
                {
                    string msg = $"文件不存在：{path}";
                    _logService.LogError(msg);
                    MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                // 检测文件是否已打开（被占用）
                if (IsFileInUse(path))
                {
                    string msg = $"文件已被打开：{path}";
                    _logService.LogInfo(msg);
                    MessageBox.Show(msg, "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                _logService.LogInfo($"打开文件：{path}");
                Process.Start(new ProcessStartInfo
                {
                    FileName = path,
                    UseShellExecute = true // 支持 Excel、WPS 等默认程序
                });
            }
            catch (Exception ex)
            {
                string msg = $"文件打开失败：{ex.Message}";
                _logService.LogError(msg);
                MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }


        private bool IsFileInUse(string filePath)
        {
            try
            {
                using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
                {
                    return false; // 文件可独占打开 → 没被占用
                }
            }
            catch (IOException)
            {
                return true; // 文件被占用
            }
        }
    }
}
